home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
The Arsenal Files 4
/
The Arsenal Files 4 (Arsenal Computer).ISO
/
casm
/
au116-as.exe
/
UNARC.CPP
< prev
next >
Wrap
C/C++ Source or Header
|
1994-12-13
|
17KB
|
589 lines
// UNARC.CPP 1 1 6666
// Dave Harris 11 11 6
// Compiled using Borland C++ ver 3.1 1 1 1 1 6666
// 03-03-94 1 .. 1 6 6
// 11111 .. 11111 666
////////////////////////////////////////////////////////////////////////
#include "au.hpp"
#define PROGRAM "UNARC" // Name of module
/*********************************************************************/
typedef struct
{
int threshold; // If number to unarc exceeds, then warn
} UNARC_INFO;
/*░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░*/
static void problem(AU *au, char *file_name, int ret_value)
{
au_printf_error(au, "\n\nProblem Unarcing %s! ", file_name);
if (ret_value == CANT_EXECUTE)
au_printf_c(au, 15, "Could not execute the unarc program\n");
else
au_printf_c(au, 15, "Unarcer returned an errorlevel of %d.\n", ret_value);
exit(ret_value);
}
/*░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░*/
static int unarc_one(AU *au, char *file_name, char *source_directory,
PACKAGE *package, int level)
{
char string2[CLENGTH]; /* build the dos commands in the string */
char string3[CLENGTH];
int ret_value;
int did_rename;
if (package->unarc == NULL)
{
au_printf_error(au, "No unarcing method specified for %s", file_name);
press_any_key(au);
return -1;
}
did_rename = rename_strict(au, package, source_directory, file_name);
build_fname(string2, source_directory, file_name);
substitute_macros(string3, package->unarc, package->overwrite,
au->unarc_paths == ON ? package->unarc_path : package->unarc_no_path,
au->answer_y == ON ? package->yes_queries : NULL,
string2);
if (package->unarc_partials == ON)
{
if (level == 0 && au->partial[0] != '\0')
sprintf(string2, "%s %s", string3, au->partial);
else
sprintf(string2, "%s *.*", string3);
}
else
strcpy(string2, string3);
if (!au->simulate)
{
ret_value = execute(au, string2, au->output,
package->yes_queries == NULL ? au->y_file : NULL,
package->memoryNeeded);
if (did_rename)
rename_strict_back(source_directory, file_name);
if (ret_value > 0)
problem(au, file_name, ret_value);
}
return 0;
}
/*░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░*/
// Some of the archivers are capable of stating where the archives are to
// go, so in the future this function might cut down on the copies a bit
static int unarc_self_extract(AU *au, char *file_name, char *source_directory,
char *dest_directory)
{
char string[FLENGTH];
char string2[FLENGTH];
char *char_ptr;
int ret_value;
int equal_dirs = TRUE;
/* Copy the file from the source directory */
if (au->scan_self == ON)
{
build_fname(string, source_directory, file_name);
ret_value = scan_one_file(au, string);
if (ret_value == au->SC_Virus_EL || (au->SC_Virus_EL == -1 && ret_value > 0))
{
add_to_bad_list(au, source_directory, file_name, 2);
return -1;
}
else if (ret_value != au->SC_NoVirus_EL || (au->SC_NoVirus_EL == -1 && ret_value != 0))
add_to_bad_list(au, au->source_directory, file_name, 4);
}
if (stricmp(source_directory, dest_directory) != 0)
{
build_fname(string, source_directory, file_name);
sprintf(string2, "copy %s *.* >NUL", string);
execute_raw(au, string2);
equal_dirs = FALSE;
}
strcpy(string2, file_name);
char_ptr=strstr(string2,"."); /* wipe out .exe or .com extension */
if (char_ptr!=NULL)
*char_ptr='\0';
if (!au->simulate)
{
if ((ret_value = execute(au, string2, au->output, au->y_file, 0)) > 0)
problem(au, file_name, ret_value);
else if (!equal_dirs)
unlink(file_name); /* in the dest (current) dir */
}
return 0;
}
/*░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░*/
static void add_paths_to_list(AU *au, LISTPTR *dest, LISTPTR *source)
{
LIST *el;
char cur_path[FLENGTH];
char path[FLENGTH];
getcwd(cur_path, FLENGTH);
for (el = source->head; el != NULL; el = el->next)
{
cd(au, el->data);
getcwd(path, FLENGTH);
dest->add(path);
cd(au, cur_path);
}
return;
}
/*░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░*/
static void display_elements(AU *au, LISTPTR *listPtr)
{
LIST *el;
for (el = listPtr->head; el != NULL; el=el->next)
au_printf(au, "%s\n", el->data);
}
/*░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░*/
static int check_existence(AU *au, char *dest_directory, LISTPTR *arc_paths,
LISTPTR *arc_files)
{
LIST *el, *el2;
char temp[FLENGTH];
char file_name[FLENGTH];
LISTPTR existing_files;
for (el = arc_files->head, el2 = arc_paths->head;
el != NULL && el2 != NULL; el=el->next, el2=el2->next)
{
/* Append extern and internal path, then the file name */
build_fname(temp, dest_directory, el2->data);
build_fname(file_name, temp, el->data);
if (access(file_name, 0x00) == 0x00)
existing_files.add(el->data);
}
if (existing_files.head != NULL)
{
if (au->warn_existing==SKIP)
{
au_printf_c(au, 15, "Skipping %s. File archive already exists on the disk\n", file_name);
return -1;
}
if (au->warn_existing==ON && au->answer_y!=ON)
{
au_printf_c(au, 15, "\aThe following files will be overwritten if you continue:\n");
display_elements(au, &existing_files);
au_printf(au, "\n");
if (!ask_continue())
return -1;
}
}
return 0;
}
/*░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░*/
int unarc(AU *au, char *file_name, char *dest_directory, LISTPTR *all_paths,
int level, BYTE through_unarc)
{
ARC_HANDLE arc_handle;
char hold_dir[FLENGTH];
char next_dir[FLENGTH];
int ret_value;
LIST *element, *element2;
LISTPTR arc_files, arc_paths, paths, too_long, hidden, dangerous;
check_for_key();
if (!ok_to_process(au, file_name))
return FALSE;
if (arc_handle.init(au, file_name) != SUCCESS)
return FALSE;
if (arc_handle.type > 0)
{
char *partial;
if (au->package[arc_handle.type].unarc_partials == ON)
partial = au->partial;
else
partial = "";
get_ns(au, partial, &arc_handle, &arc_paths, &arc_files, &paths,
&too_long, &hidden, &dangerous);
arc_handle.deinit(au);
if (dangerous.head != NULL)
{
au_printf_error(au, "The following paths are unpredictable. AU will not process this file:\n");
display_elements(au, &dangerous);
return FALSE;
}
if (paths.head != NULL)
{
if (au->warn_path==SKIP)
{
au_printf_c(au, 15, "Skipping %s. Paths exist in the archive\n", file_name);
return FALSE;
}
if (au->warn_path==ON && au->answer_y!=ON)
{
au_printf_c(au, 15, "\aThe following paths will be used/created:\n");
display_elements(au, &paths);
au_printf(au, "\n");
if (!ask_continue())
return FALSE;
}
}
if (too_long.head != NULL)
{
if (au->warn_non_dos==SKIP)
{
au_printf_c(au, 15, "Skipping %s. Non-dos files exist in the archive\n", file_name);
return FALSE;
}
if (au->warn_non_dos==ON && au->answer_y!=ON)
{
au_printf_c(au, 15, "The following internal file names are too long:\n");
display_elements(au, &too_long);
au_printf(au, "\n");
if (!ask_continue())
return FALSE;
}
}
if (hidden.head != NULL)
{
if (au->warn_hidden == SKIP)
{
au_printf_c(au, 15, "Skipping %s. Hidden/System files exist in the archive\n", file_name);
return FALSE;
}
if (au->warn_hidden == ON && au->answer_y!=ON)
{
au_printf_c(au, 15, "The following internal files have hidden or system attributes:\n");
display_elements(au, &hidden);
au_printf(au, "\n");
if (!ask_continue())
return FALSE;
}
}
if (au->package[arc_handle.type].overwrite_int_check == ON &&
(au->warn_existing == ON || au->warn_existing == SKIP))
{
if (check_existence(au, dest_directory, &arc_paths, &arc_files) < 0)
return FALSE;
}
cd(au, dest_directory, hold_dir);
{
char string[180];
build_fname(string, hold_dir, file_name);
if (!au->no_extra)
{
if (!through_unarc)
au_printf(au, " ");
au_printf(au, "@?6Unarcing @?1%s@?H to %s", string, dest_directory);
}
if (through_unarc)
act_log_printf(au, " + UNARC : %s to %s", string, dest_directory);
if (level > 0)
{
if (!au->no_extra)
au_printf_c(au, 15, " (level %d)", level+1);
act_log_printf(au, " (level %d)", level+1);
}
if (!au->no_extra)
au_printf(au, "\n");
act_log_printf(au, "\n");
}
if (arc_handle.is_self)
ret_value = unarc_self_extract(au, file_name, hold_dir,
dest_directory);
else
ret_value = unarc_one(au, file_name, hold_dir,
&au->package[arc_handle.type], level);
if (ret_value < 0)
return FALSE;
if (all_paths != NULL && au->unarc_paths == ON)
add_paths_to_list(au, all_paths, &paths);
au->num_processed[level]++;
if (au->recurse == ON && !au->simulate)
{
for (element = arc_files.head, element2 = arc_paths.head;
element != NULL;
element = element->next, element2 = element2->next)
{
if (au->unarc_paths == ON)
cd(au, element2->data);
getcwd(next_dir, FLENGTH);
unarc(au, element->data, next_dir, all_paths, level+1,
through_unarc);
if (au->unarc_paths == ON)
cd(au, dest_directory);
}
}
cd(au, hold_dir);
if (au->delete_behind == ON && !au->simulate)
unlink(file_name);
return TRUE;
}
else
arc_handle.deinit(au);
return FALSE;
}
/*░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░*/
static int unarc_internal(AU *au, char *file_name)
{
unarc(au, file_name, au->dest_directory, NULL, 0, TRUE);
return 0;
}
/*░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░*/
static void end_program(void)
{
if (glob_au->y_file[0] != '\0')
unlink(glob_au->y_file);
return;
}
/*░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░*/
static void ReadCFGInfo(AU *au, CFG_HANDLE *cfg_handle)
{
char string[200],
string2[200],
string3[200];
UNARC_INFO *in = (UNARC_INFO *)au->info;
for(EVER)
{
if (cfg_handle->read_line(au, string)==EOF)
break;
split_string(string, string2);
split_string(string, string3);
if (string2[0] == '\0')
continue;
strcpy(au->curOpt, string2);
au->curVal = string3;
switch (toupper(string2[1]) << 8 | toupper(string2[0]))
{
case 'BE': // Begin
return;
case 'DE': // Delete_behind
au->delete_behind = get_value(au, OFF | ON);
break;
case 'RE': // Recurse
au->recurse = get_value(au, OFF | ON);
break;
case 'SE': // Self_Extracts
au->self_extracts = get_value(au, OFF | ON);
break;
case 'TH': // Threshold
in->threshold = atoi(string3);
break;
case 'DO': // Dont_process
au->dont_touch.add(string3);
break;
case 'PA': // Paths
au->unarc_paths = get_value(au, OFF | ON);
break;
case 'SC': // Sc Slf Extracts
au->scan_self = get_value(au, OFF | ON);
break;
case 'WA':
if (stricmp(string2, "WARN_NON_DOS")==0)
au->warn_non_dos = get_value(au, OFF | ON | SKIP);
else if (stricmp(string2, "WARN_PATH") == 0)
au->warn_path = get_value(au, OFF | ON | SKIP);
else if(stricmp(string2, "WARN_HIDDEN") == 0)
au->warn_hidden = get_value(au, OFF | ON | SKIP);
else
au->warn_existing = get_value(au, OFF | ON | SKIP);
break;
default:
cfg_handle->invalid_option(au, string2);
}
}
}
/*░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░*/
static BYTE parse_comm_line(AU *au, char option, char *cur_argv,
PARSE_TYPE type)
{
switch (type)
{
case PARSE_PARAM_OPTION:
switch (option)
{
case 'A':
strcat(au->partial, cur_argv);
strcat(au->partial, " ");
break;
case 'D': /* Delete behind on/off */
au->delete_behind = get_value(au, OFF | ON);
break;
case 'R': /* Recursive on/off */
au->recurse = get_value(au, OFF | ON);
break;
case 'X':
au->self_extracts = get_value(au, OFF | ON);
break;
case 'Y':
au->answer_y = get_value(au, OFF | ON);
break;
case 'P':
if (toupper(*cur_argv) == 'A')
{
strcpy(au->curOpt, "-PA");
au->curVal = cur_argv+1;
au->unarc_paths = get_value(au, OFF | ON);
}
break;
case 'W':
if (toupper(*cur_argv) == 'P')
{
strcpy(au->curOpt, "-WP");
au->curVal = cur_argv+1;
au->warn_path = get_value(au, OFF | ON | SKIP);
}
else if (toupper(*cur_argv) == 'N')
{
strcpy(au->curOpt, "-WN");
au->curVal = cur_argv+1;
au->warn_non_dos = get_value(au, OFF | ON | SKIP);
}
else if (toupper(*cur_argv) == 'H')
{
strcpy(au->curOpt, "-WH");
au->curVal = cur_argv+1;
au->warn_hidden = get_value(au, OFF | ON | SKIP);
}
else if (toupper(*cur_argv) == 'H')
{
strcpy(au->curOpt, "-WE");
au->curVal = cur_argv+1;
au->warn_existing = get_value(au, OFF | ON | SKIP);
}
break;
case '?':
au_syntax_message(au, "Unarc");
au_printf(au,
"[@?3options@?H] [@?1[src path\\]filespec@?H] [@?Bpartials@?H] [dest path]\n\n");
au_param_heading(au);
au_printf(au,
"@?3-D@?Hon|off Delete_behind\n"
"@?3-R@?Hon|off Recurse\n"
"@?3-X@?Hon|off self eXtracts\n"
"@?3-Y@?Hon|off answer Y to all questions\n"
"@?3-A@?Hon|off Addition parameter to pass to the unarchiver\n"
"@?3-PA@?Hon|off unarc into PAths stored in the archive if any\n"
"@?3-WP@?Hon|off|skip Warn if archive contains Paths\n"
"@?3-WN@?Hon|off|skip Warn if archive contains Non-DOS file names\n"
"@?3-WH@?Hon|off|skip Warn if archive contains Hidden or system files\n"
"@?3-WE@?Hon|off|skip Warn if archive contains files that already Exist\n");
exit (0);
default:
au_invalid_option(au, PROGRAM, option);
}
return TRUE;
case PARSE_FILESPEC:
if (au->process_list.head == NULL)
au->process_list.add(cur_argv);
else
{
if (au->dest_directory[0]=='\0' &&
(chdir(cur_argv)!=-1 || strstr(cur_argv,":") || strstr(cur_argv,"\\")))
{
cd(au, au->cur_directory);
strcpy(au->dest_directory, cur_argv);
}
else
{
strcat(au->partial, cur_argv);
strcat(au->partial, " ");
}
}
cur_argv[0]='\0'; /* destroy this command line parameter, so
it is not added to the list again */
return TRUE;
}
return FALSE;
}
/*░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░*/
int main_unarc(AU *au, int argc, char *argv[])
{
int i;
UNARC_INFO *in;
in = new UNARC_INFO;
memset(in, '\0', sizeof(UNARC_INFO));
au->info = in;
in->threshold = -1;
atexit(end_program);
ReadGlobalCFGInfo(au, au->cfg_file, PROGRAM, ReadCFGInfo);
generic_parse_comm_line(au, argc, argv, parse_comm_line);
/********************************************************************/
/* get all the file names and put them on the list */
cd(au, au->source_directory);
/* Restore it so we get full path name */
getcwd(au->source_directory, FLENGTH);
check_threshold(au, in->threshold, au->answer_y==ON);
/********************************************************************
build file full of Y's
********************************************************************/
if (au->answer_y == ON)
{
HANDLE handle;
build_fname(au->y_file, au->cur_directory, "y__file.$$$");
handle.create(au->y_file, S_IWRITE);
for (i=0 ; i < 100 ; i++)
handle.write_text("Y\n");
handle.close();
}
cd(au, au->cur_directory); /* Dest might be empty */
cd(au, au->dest_directory);
getcwd(au->dest_directory,FLENGTH); /* Restore it so we get full path name */
cd(au, au->source_directory);
process_files(au, unarc_internal);
if (!au->no_extra)
{
au_printf_c(au, 15, "\nFiles Unarced = %d\n", au->num_processed[0]);
for (i=1; i<10; i++)
{
if (au->num_processed[i]==0)
break;
au_printf_c(au, 15, "Files Unarced (Level %d) = %d\n", i+1, au->num_processed[i]);
}
}
return 0;
}